package com.adingxiong.cft.websocket;

import com.adingxiong.cft.constant.WebSocketConstant;
import com.adingxiong.cft.entity.chat.Message;
import com.alibaba.fastjson.JSONObject;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ConcurrentHashMap;

/**
 * @ClassName MyServerHandler
 * @Description TODO
 * @Author xiongchao
 * @Date 2021/4/8 13:47
 **/
@Slf4j
public class MyServerHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    public static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    /**
     * 存户用户个 通道信息
     */
    public static ConcurrentHashMap<Integer,Channel> userChannel =new ConcurrentHashMap<>();


    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        JSONObject object = JSONObject.parseObject(msg.text());

        Message message = JSONObject.toJavaObject(object, Message.class);
        // 记录发送人和 通道
        userChannel.put(message.getFrom(),ctx.channel());

        log.info("记录消息:{}" ,message.toString());

        if(message.getEvent().equals(WebSocketConstant.HEAR_BEAT)) {
            log.info("心跳检测~~~");
            return;
        }

        if( message.getTo().equals(WebSocketConstant.ALL)) {
            log.info("群聊消息");
            //给 当前在线用户的所有人发送消息
            for(Channel channel : clients) {
                //  过滤掉本人
                if(channel != ctx.channel()) {
                    channel.writeAndFlush(postMsg(msg.text()));
                }
            }
        } else {
            //私聊  单独发送给指定用户
            Channel channel = userChannel.get(message.getTo());
            channel.writeAndFlush(postMsg(msg.text()));
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        clients.remove(ctx.channel());
        log.info("用户: {} 离开房间");
    }


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("用户 : {} 加入房间",ctx.channel());
        clients.add(ctx.channel());

    }

    /**
     * 异常监听  有问题自己关闭连接
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }


    /**
     * 消息格式统一封装
     * @param msg
     * @return
     */
    public TextWebSocketFrame postMsg (String msg) {
        return new TextWebSocketFrame(msg);
    }
}
